package com.jiudengnile.liushu.biz.ao.impl;

import javax.servlet.http.HttpSession;

import wint.help.biz.result.Result;
import wint.help.biz.result.ResultSupport;
import wint.help.biz.result.ResultType;
import wint.lang.utils.StringUtil;
import wint.mvc.holder.WintContext;

import com.jiudengnile.liushu.biz.ao.UserAO;
import com.jiudengnile.liushu.biz.bo.BaseUserBO;
import com.jiudengnile.liushu.biz.constants.SessionAttributes;
import com.jiudengnile.liushu.biz.domains.BaseUserDO;
import com.jiudengnile.liushu.biz.resultcodes.UserResultCodes;
import com.jiudengnile.liushu.common.user.PasswordEncrypter;

public class UserAOImpl extends BaseAO implements UserAO {

	private BaseUserBO baseUserBO;
	
	public Result handleLogout() {
		Result result = new ResultSupport(false);
		try {
			applyLogout();
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("registerByNick error", e);
		}
		return result;
	}
	
	@Override
	public Result registerByNick(BaseUserDO baseUserDO) {
		Result result = new ResultSupport(false);
		try {
			result.setResultType(ResultType.CURRENT_TARGET);
			String nick = baseUserDO.getNick();
			BaseUserDO inDb = baseUserBO.queryByNick(nick);
			if (inDb != null) {
				result.setResultCode(UserResultCodes.USER_HAS_BEEN_EXIST_BY_NICK);
				return result;
			}
			
			String encryptedPassword = PasswordEncrypter.encrypt(baseUserDO.getPassword());
			baseUserDO.setPassword(encryptedPassword);
			long userId = baseUserBO.create(baseUserDO);
			
			applyLogin(userId, baseUserDO.getNick());
			
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("registerByNick error", e);
		}
		return result;
	}

	@Override
	public Result handleLogin(BaseUserDO baseUserDO) {
		Result result = new ResultSupport(false);
		try {
			result.setResultType(ResultType.CURRENT_TARGET);
			// 支持用户名和电子邮箱都可以登录
			String nick = baseUserDO.getNick();
			BaseUserDO inDb = null;
			if (!StringUtil.isEmpty(nick)) {
				inDb = loginByNick(baseUserDO, result);
			} else {
				inDb = loginByEmail(baseUserDO, result);
			}
			if (inDb == null) {
				return result;
			}
			applyLogin(inDb.getId(), inDb.getNick());
			
			result.setSuccess(true);
		} catch (Exception e) {
			log.error("handleLogin error", e);
		}
		return result;
	}
	
	private void applyLogin(long userId, String nick) {
		HttpSession session = WintContext.getFlowData().getSession();
		session.setAttribute(SessionAttributes.USER_ID, userId);
		session.setAttribute(SessionAttributes.USER_NICK, nick);
	}
	
	private void applyLogout() {
		HttpSession session = WintContext.getFlowData().getSession();
		session.removeAttribute(SessionAttributes.USER_ID);
		session.removeAttribute(SessionAttributes.USER_NICK);
	}
	
	private BaseUserDO loginByNick(BaseUserDO baseUserDO, Result result) {
		BaseUserDO inDb = baseUserBO.queryByNick(baseUserDO.getNick());
		if (inDb == null) {
			result.setResultCode(UserResultCodes.USER_NOT_EXIST_BY_NICK_FOR_LOGIN);
			return null;
		}
		if (!checkUserPassword(inDb, baseUserDO, result)){
			return null;
		}
		return inDb;
	}
	
	private boolean checkUserPassword(BaseUserDO inDb, BaseUserDO baseUserDO, Result result) {
		String inputPassword = PasswordEncrypter.encrypt(baseUserDO.getPassword());
		String inDbPassword = inDb.getPassword();
		if (StringUtil.equals(inputPassword, inDbPassword)) {
			return true;
		}
		result.setResultCode(UserResultCodes.PASSWORD_INCORRECT);
		return false;
	}
	
	private BaseUserDO loginByEmail(BaseUserDO baseUserDO, Result result) {
		BaseUserDO inDb = baseUserBO.queryByEmail(baseUserDO.getEmail());
		if (inDb == null) {
			result.setResultCode(UserResultCodes.USER_NOT_EXIST_BY_EMAIL_FOR_LOGIN);
			return null;
		}
		if (!checkUserPassword(inDb, baseUserDO, result)){
			return null;
		}
		return inDb;
	}
	

	public void setBaseUserBO(BaseUserBO baseUserBO) {
		this.baseUserBO = baseUserBO;
	}

}
